home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Shutdown FX 1.5 source Folder / Shutdown FX ƒ / code ƒ / ◊ prefs.c < prev    next >
Encoding:
Text File  |  1994-04-09  |  8.7 KB  |  313 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        prefs.c
  4.  
  5. Purpose:    This module handles creating/opening/closing/updating
  6.             the preference file, and copying the preference file
  7.             data into our globals (and back).
  8.  
  9.  
  10. Shutdown FX -=- graphic effects on shutdown
  11. Copyright (C) 1993-4, Mark Pilgrim & Dave Blumenthal
  12.  
  13. This program is free software; you can redistribute it and/or modify
  14. it under the terms of the GNU General Public License as published by
  15. the Free Software Foundation; either version 2 of the License, or
  16. (at your option) any later version.
  17.  
  18. This program is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. GNU General Public License for more details.
  22.  
  23. You should have received a copy of the GNU General Public License
  24. along with this program in a file named "GNU General Public License".
  25. If not, write to the Free Software Foundation, 675 Mass Ave,
  26. Cambridge, MA 02139, USA.
  27.  
  28. \**********************************************************************/
  29.  
  30. #include "init.h"
  31. #include "prefs.h"
  32. #include "main.h"
  33. #include "Folders.h"
  34.  
  35. #define        PREFS_FILE_NAME            "\pShutdown FX prefs"
  36. #define        PREFS_TYPE                'pref'
  37. #define        CREATOR                    '§fx§'
  38. #define        PREFS_HEADER_VERSION    1
  39.  
  40. typedef struct
  41. {
  42.     unsigned char    onrestart;
  43.     unsigned char    onshutdown;
  44.     unsigned char    sequential;
  45.     unsigned char    isvirgin;
  46.     int                whichwipe;
  47. } PrefStruct;
  48.  
  49. Boolean            gHasFSSpecs;
  50.  
  51. /* internal globals for use in prefs.c only */
  52. Boolean            gCanSavePrefs;
  53. PrefStruct        thePrefs;
  54. long            gPrefsFilePos;
  55.  
  56. /*-----------------------------------------------------------------------------------*/
  57. /* internal stuff for prefs.c                                                        */
  58.  
  59. int OpenPrefsFile(int *prefsFileID);
  60. int SetupNewPrefsFile(int prefsFileID);
  61. void ClosePrefsFile(int prefsFileID);
  62. int GetNextPrefs(int prefsFileID);
  63. int SavePrefs(int prefsFileID);
  64. int CheckVersion(int prefsFileID);
  65. int GetFileID(void);
  66. int CheckFileID(void);
  67. int Virgin(int prefsFileID);
  68. void DefaultPrefs(void);
  69. void CopyGlobalsToPrefs(void);
  70. void CopyPrefsToGlobals(void);
  71.  
  72. void SaveThePrefs(void)
  73. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  74. {
  75.     int            prefsFileID;
  76.     
  77.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  78.     {
  79.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  80.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  81.         SavePrefs(prefsFileID);            /* save prefs to disk */
  82.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  83.     }
  84. }
  85.  
  86. int PreferencesInit(void)
  87. {
  88.     int                prefsFileID;
  89.     int                err;
  90.     
  91.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  92.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  93.     if (err!=prefs_allsWell)
  94.     {
  95.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  96.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  97.         return err;
  98.     }
  99.     
  100.     err=CheckVersion(prefsFileID);        /* check prefs version */
  101.     if (err!=prefs_allsWell)
  102.     {
  103.         ClosePrefsFile(prefsFileID);
  104.         return err;
  105.     }
  106.     
  107.     GetFPos(prefsFileID, &gPrefsFilePos);
  108.     err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  109.     if (err==prefs_noMorePrefsErr)        /* or not */
  110.         return (Virgin(prefsFileID));    /* can't find our prefs struct */
  111.         
  112.     if (err!=prefs_allsWell)            /* any other error, just abort */
  113.     {
  114.         ClosePrefsFile(prefsFileID);
  115.         return err;
  116.     }
  117.     
  118.     CopyPrefsToGlobals();                /* copy prefs struct to program globals */
  119.     ClosePrefsFile(prefsFileID);        /* close prefs file */
  120.     gCanSavePrefs=TRUE;
  121.     return prefs_allsWell;                /* piece o' cake */
  122. }
  123.  
  124. int OpenPrefsFile(int *prefsFileID)
  125. {
  126.     int                thisFile;
  127.     OSErr            isHuman;
  128.     int                vRefNum;
  129.     long            dirID;
  130.     FSSpec            prefsFile;
  131.     FInfo            prefsInfo;
  132.     Boolean            newPrefs;
  133.     unsigned char    *name=PREFS_FILE_NAME;
  134.     
  135.     newPrefs=FALSE;
  136.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  137.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  138.     
  139.     if (isHuman!=noErr)        /* screwed up already?!? */
  140.         return prefs_cantOpenPrefsErr;
  141.     if (gHasFSSpecs)
  142.     {
  143.         isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  144.         if (isHuman!=noErr)
  145.         {
  146.             if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  147.             {
  148.                 isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  149.                 if (isHuman!=noErr)                                        /* or not */
  150.                     return prefs_cantCreatePrefsErr;
  151.                 newPrefs=TRUE;        /* signal that prefs file is new */
  152.             }
  153.             else return prefs_cantOpenPrefsErr;
  154.         }
  155.         isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  156.         *prefsFileID=thisFile;        /* store file reference number */
  157.         if (isHuman!=noErr)
  158.             return prefs_cantOpenPrefsErr;
  159.     }
  160.     else
  161.     {
  162.         /* try to open prefs file */
  163.         isHuman=HOpen(vRefNum, dirID, name, fsRdWrPerm, &thisFile);
  164.         *prefsFileID=thisFile;
  165.         if (isHuman!=noErr)
  166.         {
  167.             if (isHuman==fnfErr)    /* prefs file does not exist */
  168.             {
  169.                 /* ...so create it */
  170.                 if (HCreate(vRefNum, dirID, name, CREATOR, PREFS_TYPE)!=noErr)
  171.                     return prefs_cantCreatePrefsErr;
  172.                 prefsInfo.fdType=PREFS_TYPE;
  173.                 prefsInfo.fdCreator=CREATOR;
  174.                 prefsInfo.fdFlags=0;
  175.                 prefsInfo.fdLocation.h=prefsInfo.fdLocation.v=0;
  176.                 prefsInfo.fdFldr=0;
  177.                 
  178.                 /* set file info of newly created prefs file */
  179.                 if (HSetFInfo(vRefNum, dirID, name, &prefsInfo)!=noErr)
  180.                     return prefs_cantCreatePrefsErr;
  181.                 
  182.                 /* NOW open the prefs file */
  183.                 isHuman=HOpen(vRefNum, dirID, name, fsRdWrPerm, &thisFile);
  184.                 *prefsFileID=thisFile;        /* store file reference number */
  185.                 if (isHuman!=noErr)
  186.                     return prefs_cantOpenPrefsErr;
  187.                 newPrefs=TRUE;                /* signal that prefs file is new */
  188.             }
  189.             else return prefs_cantOpenPrefsErr;
  190.         }
  191.     }
  192.     if (newPrefs)
  193.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  194.     
  195.     return prefs_allsWell;
  196. }
  197.  
  198. int SetupNewPrefsFile(int prefsFileID)
  199. /* this writes the prefs version number to the newly created prefs file, so we can
  200.    tell if the prefs file was created by a later version of the program and is
  201.    therefore in a format that we don't support -- forward compatability!  what
  202.    a concept! */
  203. {
  204.     long            count;
  205.     int                temp;
  206.     
  207.     gPrefsFilePos=2L;
  208.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  209.         return prefs_diskWriteErr;
  210.     
  211.     SetFPos(prefsFileID, 1, 0L);
  212.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  213.     count=2L;
  214.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  215.         return prefs_diskWriteErr;        
  216.     
  217.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  218. }
  219.  
  220. void ClosePrefsFile(int prefsFileID)
  221. {
  222.     FSClose(prefsFileID);                /* close file on disk */
  223.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  224. }
  225.  
  226. int GetNextPrefs(int prefsFileID)
  227. {
  228.     OSErr        isHuman;
  229.     long        count;
  230.     
  231.     count=sizeof(thePrefs);
  232.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  233.     if (isHuman==eofErr)    /* no more left */
  234.         return prefs_noMorePrefsErr;
  235.     if (isHuman!=noErr)        /* some other error */
  236.         return prefs_diskReadErr;
  237.     
  238.     return prefs_allsWell;
  239. }
  240.  
  241. int SavePrefs(int prefsFileID)
  242. {
  243.     long        oldEOF;
  244.     long        count;
  245.     
  246.     GetEOF(prefsFileID, &oldEOF);
  247.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  248.     {
  249.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  250.             return prefs_diskWriteErr;
  251.     }
  252.     
  253.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  254.     count=sizeof(thePrefs);
  255.     /* write prefs struct and return appropriate error code */
  256.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  257.         prefs_diskWriteErr : prefs_allsWell;
  258. }
  259.  
  260. int CheckVersion(int prefsFileID)
  261. {
  262.     OSErr        isHuman;
  263.     long        count;
  264.     int            temp;
  265.     
  266.     count=2L;
  267.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  268.     if (isHuman!=noErr)
  269.         return prefs_diskReadErr;
  270.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  271.         return prefs_versionNotSupportedErr;
  272.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  273.         return SetupNewPrefsFile(prefsFileID);
  274.     
  275.     return prefs_allsWell;
  276. }
  277.  
  278. int Virgin(int prefsFileID)
  279. {
  280.     int            err;
  281.     
  282.     DefaultPrefs();
  283.     CopyGlobalsToPrefs();
  284.     err=SavePrefs(prefsFileID);
  285.     
  286.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  287. }
  288.  
  289. void DefaultPrefs(void)
  290. {
  291.     gIsVirgin=gOnShutdown=0xFF;
  292.     gSequential=gOnRestart=0x00;
  293.     gWhichWipe=0;
  294. }
  295.  
  296. void CopyGlobalsToPrefs(void)
  297. {
  298.     thePrefs.onrestart=gOnRestart;
  299.     thePrefs.onshutdown=gOnShutdown;
  300.     thePrefs.sequential=gSequential;
  301.     thePrefs.whichwipe=gWhichWipe;
  302.     thePrefs.isvirgin=gIsVirgin;
  303. }
  304.  
  305. void CopyPrefsToGlobals(void)
  306. {
  307.     gOnRestart=thePrefs.onrestart;
  308.     gOnShutdown=thePrefs.onshutdown;
  309.     gSequential=thePrefs.sequential;
  310.     gWhichWipe=thePrefs.whichwipe;
  311.     gIsVirgin=thePrefs.isvirgin;
  312. }
  313.